import { Injectable } from '@nestjs/common'
import { InjectRepository } from '@nestjs/typeorm'
import { Allocate } from 'src/entity/Allocate'
import { Asset } from 'src/entity/Asset'
import { Borrow } from 'src/entity/Borrow'
import { Budget } from 'src/entity/Budget'
import { Easter } from 'src/entity/Easter'
import { Fix } from 'src/entity/Fix'
import { Purchase } from 'src/entity/Purchase'
import { Receive } from 'src/entity/Receive'
import { Scrap } from 'src/entity/Scrap'
import { Task } from 'src/entity/Task'
import { Type } from 'src/entity/Type'
import { Connection, IsNull, Repository } from 'typeorm'

@Injectable()
export class AssetsService {
  constructor(
    @InjectRepository(Asset)
    private assetRepository: Repository<Asset>,
    private connection: Connection,
  ) { }

  // 分页查询
  async getPageList({
    pageRequest: { pageIndex, pageSize },
    assetCode,
    typeId,
    branchName,
    user,
    assetName,
    warehouseId,
    assetStatus,
    orgId,
  }) {
    const sqlAllData = await this.assetRepository.find({
      where: {
        assetCode: assetCode,
        typeId: typeId ? parseInt(typeId) : undefined,
        branchName: branchName,
        user: user,
        assetName: assetName,
        warehouseId: warehouseId ? parseInt(warehouseId) : undefined,
        assetStatus: assetStatus,
      },
    })
    const sqlData = await this.assetRepository.find({
      where: {
        assetCode: assetCode,
        typeId: typeId ? parseInt(typeId) : undefined,
        branchName: branchName,
        user: user,
        assetName: assetName,
        warehouseId: warehouseId ? parseInt(warehouseId) : undefined,
        assetStatus: assetStatus,
      },
      skip: (pageIndex - 1) * pageSize,
      take: pageSize,
    })

    return {
      content: sqlData.map((item) => {
        return {
          ...item,
          typeId: item.typeId.toString(),
          warehouseId: item.warehouseId.toString(),
        }
      }),
      total: sqlAllData.length,
    }
  }

  async getHomeTag({ orgId }) {
    const data = []
    await this.connection.transaction(async (manager) => {
      const [assetSqlData, assetCount] = await manager.findAndCount(Asset, {
        where: {
          branchId: orgId,
          isDelete: IsNull(),
        },
      })
      data.push(assetCount)
      const [purchaseSqlData, purchaseCount] = await manager.findAndCount(
        Purchase,
        {
          where: {
            purchaseBranchId: orgId,
            isDelete: IsNull(),
          },
        },
      )
      data.push(purchaseCount)
      const [scrapSqlData, scrapCount] = await manager.findAndCount(Asset, {
        where: {
          branchId: orgId,
          assetStatus: '5',
        },
      })
      data.push(scrapCount)
      const [fixSqlData, fixCount] = await manager.findAndCount(Fix, {
        where: {
          receiveBranchId: orgId,
          isDelete: IsNull(),
        },
      })
      data.push(fixCount)
    })
    return data
  }

  async getCountOfType({ orgId }) {
    const data = await new Promise((res, rej) => {
      this.connection.transaction(async (manager) => {
        const typeSqlData = await manager.find(Type, {
          where: {
            isDelete: IsNull(),
          },
        })

        const asyncList = typeSqlData.map((type) => {
          return new Promise(async (res, rej) => {
            const [assetSqlData, assetCount] = await manager.findAndCount(
              Asset,
              {
                where: {
                  isDelete: IsNull(),
                  typeId: type.id,
                  branchId: orgId,
                },
              },
            )
            res({
              typeName: type.typeName,
              number: assetCount || 0,
            })
          })
        })
        const data = await Promise.all(asyncList)
        res(data)
      })
    })
    return data
  }

  async getReceiveCount({ orgId }) {
    const data = []
    await this.connection.transaction(async (manager) => {
      const [, budgetCount] = await manager.findAndCount(Budget, {
        where: {
          receiveBranchId: orgId,
          isDelete: IsNull(),
        },
      })
      data.push(budgetCount || 0)

      const [, purchaseCount] = await manager.findAndCount(Purchase, {
        where: {
          purchaseBranchId: orgId,
          isDelete: IsNull(),
        },
      })
      data.push(purchaseCount || 0)

      const [, fixCount] = await manager.findAndCount(Fix, {
        where: {
          receiveBranchId: orgId,
          isDelete: IsNull(),
        },
      })
      data.push(fixCount || 0)

      const [, receiveCount] = await manager.findAndCount(Receive, {
        where: {
          receiveBranchId: orgId,
          isDelete: IsNull(),
        },
      })
      data.push(receiveCount || 0)

      const [, allocateCount] = await manager.findAndCount(Allocate, {
        where: {
          allocateInBranchId: orgId,
          isDelete: IsNull(),
        },
      })
      data.push(allocateCount || 0)

      const [, scrapCount] = await manager.findAndCount(Scrap, {
        where: {
          receiveBranchId: orgId,
          isDelete: IsNull(),
        },
      })
      data.push(scrapCount || 0)

      const [, borrowCount] = await manager.findAndCount(Borrow, {
        where: {
          receiveBranchId: orgId,
          isDelete: IsNull(),
        },
      })
      data.push(borrowCount || 0)

      const [, easterCount] = await manager.findAndCount(Easter, {
        where: {
          receiveBranchId: orgId,
          isDelete: IsNull(),
        },
      })
      data.push(easterCount || 0)
    })

    return data
  }

  async assetWarning({ orgId }) {
    const data = []
    await this.connection.transaction(async (manager) => {
      // 部门资产总数
      const [, allAssetsCount] = await manager.findAndCount(Asset)
      // 正常资产总数小于50个
      const [, normalAssetsCount] = await manager.findAndCount(Asset, {
        where: {
          assetStatus: '1',
          isDelete: IsNull(),
        },
      })
      if (normalAssetsCount < 50) {
        data.push({
          todoName: '部门正常状态的资产总数小于50件，请注意补充部门资产库存',
          todoType: 0,
        })
      }
      // 报废资产总数大于部门总资产百分之10
      // 报废资产总数
      const [, scrapAssetsCount] = await manager.findAndCount(Asset, {
        where: {
          assetStatus: '5',
        },
      })
      if (scrapAssetsCount > allAssetsCount * 0.1) {
        data.push({
          todoName:
            '报废资产总数大于部门总资产百分之10，请注意部门资产使用情况',
          todoType: 0,
        })
      }
      // 维修资产总数大于部门总资产百分之10
      const [, fixAssetsCount] = await manager.findAndCount(Asset, {
        where: {
          assetStatus: '6',
          isDelete: IsNull(),
        },
      })
      if (fixAssetsCount > allAssetsCount * 0.1) {
        data.push({
          todoName:
            '维修中资产总数大于部门总资产百分之10，请注意部门资产使用情况',
          todoType: 0,
        })
      }
      // 借出资产总数大于部门总资产百分之5
      const [, borrowAssetsCount] = await manager.findAndCount(Borrow, {
        where: {
          borrowOutBranchId: orgId,
          isDelete: IsNull(),
        },
      })
      if (borrowAssetsCount > allAssetsCount * 0.05) {
        data.push({
          todoName: '借出资产总数大于部门总资产百分之5，请注意部门资产流出情况',
          todoType: 0,
        })
      }
      // 部门进行中的申请审核大于10条
      const [, taskCount] = await manager.findAndCount(Task, {
        where: [
          {
            receiveBranchId: orgId,
            taskStatus: '0',
            isDelete: IsNull(),
          },
          {
            receiveBranchId: orgId,
            taskInStatus: '0',
            isDelete: IsNull(),
          },
          {
            receiveOutBranchId: orgId,
            taskOutDate: '0',
            isDelete: IsNull(),
          },
        ],
      })
      if (taskCount > 50) {
        data.push({
          todoName:
            '部门进行中的申请审核大于10条，请及时完成正在进行中的申请审核',
          todoType: 0,
        })
      }
    })
    return data
  }
}
